home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 49 / Amiga Format CD49 (2000-01-17)(Future Publishing)(GB)(Track 1 of 3)[!][issue 2000-02].iso / -in_the_mag- / banging_the_metal / ncr_scsi / cd_player_bas next >
Text File  |  1999-12-03  |  20KB  |  613 lines

  1. 100 REMark Amiga Qdos 3.23 SCSI CD player
  2. 110 REMark Expects a C=/DKB 4091 and a CD
  3. 120 REMark drive assigned to SCSI unit 1;
  4. 130 REMark tested with NEC MultiSpin 2xi,
  5. 135 REMark then adapted for Toshiba 3401.
  6. 137 REMark REQUEST_SENSE & DRIVE_IDENT=OK
  7. 138 REMark NCR CD PLAY etc. are rejected.
  8. 140 REMark SCSI code should also suit CSA
  9. 150 REMark Magnum, PP Zeus & Warp Engines
  10. 160 REMark once the value of NCR53c710 is
  11. 170 REMark adjusted to  point to the base
  12. 180 REMark of your controller registers.
  13. 190 :
  14. 200 WINDOW 512,216,0,0
  15. 250 CSIZE #0,2,0:CSIZE 0,0 : CSIZE #2,1,0
  16. 300 WINDOW #2,512,210,0,6
  17. 350 POKE_W HEX("DFF182"),15
  18. 400 POKE_W HEX("DFF184"),4000
  19. 450 :
  20. 500 SCSI_VARS
  21. 550 PRINT #0;"Initialising SCSI..."
  22. 600 NCR_RESET
  23. 610 REMark SUSPEND_TASK is the only Toolkit extension
  24. 620 REMark needed by this program; it allows time for
  25. 630 REMark the NEC 2x CD drive to respond to commands
  26. 640 REMark that it needs time to digest.  It could be
  27. 650 REMark replaced by a  FOR loop delay to suit your
  28. 660 REMark own CD drive if you lack TURBO TOOLKIT.
  29. 670 SUSPEND_TASK 200 :REMark Wait for reset
  30. 680 REPeat init
  31. 690   TEST_READY CD
  32. 700   CD_TRACKS
  33. 710   IF sense<>0 AND sense<>6
  34. 715     PRINT #0;"CD drive unit"! CD !"is not responding."
  35. 720     PRINT #0;"Type an alternative CD unit number"
  36. 730     PRINT #0;"(not"!CD;") or tap ENTER to try again: ";
  37. 735     PAN #0,0,115 : t$=INKEY$(#0,-1)
  38. 740     PAN #0,0,116 : PRINT #0;t$
  39. 745     IF CODE(t$)<33:NEXT init
  40. 750     IF t$ INSTR "0123456" : CD=t$
  41. 760   ELSE 
  42. 770     EXIT init
  43. 780   END IF 
  44. 790 END REPeat init
  45. 810 CLS #0
  46. 850 CD_MENU
  47. 990 :
  48. 1100 DEFine PROCedure SCSI_VARS
  49. 1120 debugging=0 : time=10000 : host%=7 : CD=1 : DAT=2
  50. 1140 null$=FILL$(CHR$(0),32)
  51. 1150 NEC=0 : STD=NOT NEC
  52. 1290 REMark Assume a 53C710 is on the Zorro 3 bus
  53. 1300 warp_rom=HEX("41000000"):REMark Second 16 Mb slot
  54. 1305 REMark Register offset is +8 Mb for A4091
  55. 1310 ncr53c710=warp_rom+8*1024*1024
  56. 1315 REMark Register offset is +256 Kb for Warp
  57. 1320 NCR_SIEN=ncr53c710
  58. 1330 NCR_SCNTL0=ncr53c710+3
  59. 1340 NCR_SCNTL1=ncr53c710+2
  60. 1350 NCR_SDID  =ncr53c710+1
  61. 1360 NCR_SOCL  =ncr53c710+4
  62. 1370 NCR_SODL  =ncr53c710+5
  63. 1400 NCR_SCID  =ncr53c710+7
  64. 1410 NCR_SBCL  =ncr53c710+8
  65. 1420 NCR_SBDL  =ncr53c710+9
  66. 1430 NCR_SIDL  =ncr53c710+10
  67. 1470 NCR_SSTAT1=ncr53c710+13
  68. 1480 NCR_SSTAT0=ncr53c710+14
  69. 1490 NCR_DSA   =ncr53c710+16 :REMark Long
  70. 1495 NCR_CTEST2=ncr53c710+21
  71. 1500 NCR_CTEST0=ncr53c710+23
  72. 1510 NCR_CTEST7=ncr53c710+24
  73. 1560 NCR_ISTAT =ncr53c710+34
  74. 1770 NCR_DCNTL =ncr53c710+56
  75. 1772 NCR_DWT   =ncr53c710+57
  76. 1775 NCR_DIEN  =ncr53c710+58
  77. 1780 NCR_DMODE =ncr53c710+59
  78. 1790 :
  79. 1800 REQ=128 : ACK=64 : BUSY=32 : SELT=16 : ATN=8
  80. 1810 :
  81. 1820 Phases%=7 : MessageOut%=6 : MessageIn%=7
  82. 1830 DataIn%=1 : Command%=2 : StatusPhase%=3
  83. 1840 DataOut%=0 :REMark 4 and 5 are reserved
  84. 1850 END DEFine SCSI_VARS
  85. 1990 :
  86. 2000 DEFine PROCedure NCR_RESET
  87. 2010 POKE NCR_SIEN,0 :REMark Mask ALL interrupts
  88. 2020 POKE NCR_SCNTL1,8+32 :REMark ESR + RST
  89. 2030 PAUSE 1 :REMark Well over 25 microseconds!
  90. 2040 POKE NCR_SCNTL1,32 :REMark Cancel RST
  91. 2050 POKE NCR_ISTAT,0 :REMark Clear Interrupt status
  92. 2060 POKE NCR_SCNTL0,192+8+4 :REMark Full Arbitration & Parity
  93. 2070 POKE NCR_DCNTL,0 :REMark SCLCK/2; 37.51 -> 50.00 MHz
  94. 2080 POKE NCR_DMODE,128 :REMark DMA Burst length 4 long words
  95. 2090 POKE NCR_DIEN,0 :REMark Mask off all DMA interrupts
  96. 2100 POKE NCR_DWT,0 :REMark Disable Watchdog timer for now
  97. 2110 POKE NCR_SCID,2^host% :REMark HOST%=7 unless arbitrating
  98. 2120 POKE NCR_CTEST0,64+32+16 :REMark BTD +GRP +Active Negation
  99. 2130 POKE NCR_CTEST7,128 :REMark or 34 (Warp) SC0 +TT1 (Bursts OK)
  100. 2140 REMark Set CTEST7=128 on a 4091 to disable burst transfers
  101. 2150 IF debugging THEN PRINT \"**** NCR controller reset."
  102. 2250 END DEFine NCR_RESET
  103. 2260 :
  104. 2270 DEFine PROCedure NCR_SELECT(target%)
  105. 2272 LOCal poll
  106. 2275 IF debugging : PRINT \"Selecting SCSI device",target%,
  107. 2280 POKE NCR_SODL,2^host%+2^target%
  108. 2290 POKE NCR_SOCL,32      :REMark Assert BUSY
  109. 2300 POKE NCR_SCNTL1,64+16 :REMark ADB + CON
  110. 2310 POKE NCR_DCNTL,8      :REMark Low level mode
  111. 2320 POKE NCR_SOCL,SELT+ATN+BUSY
  112. 2330 POKE NCR_SOCL,SELT+ATN
  113. 2340 REMark Wait till target asserts BUSY
  114. 2350 FOR poll=1 TO time: IF PEEK(NCR_SBCL) && BUSY : EXIT poll
  115. 2351 selected=poll<time
  116. 2352 IF debugging
  117. 2353   IF selected
  118. 2355     PRINT "Ready after ";poll
  119. 2356   ELSE PRINT "Timeout!"
  120. 2357   END IF 
  121. 2358 END IF 
  122. 2360 POKE NCR_SOCL,ATN :REMark ATN sets I/O for MESSAGE OUT
  123. 2370 REMark POKE NCR_SOCL,0    :REMark Deassert ATN
  124. 2380 FOR poll=1 TO time: IF PEEK(NCR_SBCL) && REQ : EXIT poll
  125. 2385 IF poll=time: PRINT #0;"REQ timeout after selection." :STOP
  126. 2390 END DEFine NCR_SELECT
  127. 2395 :
  128. 2400 DEFine PROCedure POLL_ALL
  129. 2405 LOCal id
  130. 2410 FOR id=0 TO 1
  131. 2420   IF NOT BUS_FREE : NCR_RESET
  132. 2430   NCR_SELECT id
  133. 2440   SHOW_STATE
  134. 2450 END FOR id
  135. 2490 POKE NCR_SOCL,0    :REMark Drop ATN
  136. 2500 END DEFine POLL_ALL
  137. 2510 :
  138. 2520 DEFine PROCedure SHOW_STATE
  139. 2530 LOCal bus,bit
  140. 2535 IF NOT debugging : RETurn
  141. 2540 bus=PEEK(NCR_SBCL)
  142. 2545 PRINT bus!!
  143. 2550 FOR bit=0 TO 7
  144. 2560   PRINT "REQACKBSYSELATNMSGC/DI/O"(bit*3+1 TO bit*3+3);
  145. 2570   IF bus && (2^(7-bit))
  146. 2575     PRINT " set   ";
  147. 2580   ELSE 
  148. 2585     PRINT " reset ";
  149. 2587   END IF 
  150. 2590 END FOR bit
  151. 2595 PRINT \"SODL = ";PEEK(NCR_SODL);" SIDL = ";PEEK(NCR_SIDL)
  152. 2600 END DEFine SHOW_STATE
  153. 2610 :
  154. 2620 DEFine FuNction BUS_FREE
  155. 2630 RETurn 0=(PEEK(NCR_SBCL) && (SELT+BUSY))
  156. 2640 END DEFine BUS_FREE
  157. 2650 :
  158. 2660 DEFine PROCedure NCR_IDENTIFY
  159. 2670 SEND_MESSAGE 128 :REMark No disconnect (yet)
  160. 2680 END DEFine NCR_IDENTIFY
  161. 2690 :
  162. 2700 DEFine PROCedure NCR_ABORT
  163. 2710 SEND_MESSAGE 6
  164. 2770 END DEFine NCR_ABORT
  165. 2780 :
  166. 2790 DEFine PROCedure MESSAGE_IN
  167. 2792 LOCal poll
  168. 2794 IF (PEEK(NCR_SBCL) && Phases%)<>MessageIn%
  169. 2796   PRINT #0;"Phase error; MESSAGE IN expected." : RETurn 
  170. 2798 END IF 
  171. 2799 message=PEEK(NCR_SBDL)
  172. 2800 POKE NCR_SOCL,ACK+MessageIn%
  173. 2810 IF debugging : PRINT "Message received: ";message
  174. 2820 FOR poll=1 TO time: IF PEEK(NCR_SBCL)<REQ : EXIT poll
  175. 2830 IF poll=time: PRINT #0;"REQ timeout after message in." :STOP
  176. 2840 POKE NCR_SOCL,MessageIn%
  177. 2845 REMark FOR poll=1 TO time: IF PEEK(NCR_SBCL) && REQ : EXIT poll
  178. 2847 REMark IF poll=time: PRINT #0;"REQ timeout after message in." :STOP
  179. 2850 END DEFine MESSAGE_IN
  180. 2860 :
  181. 2870 DEFine PROCedure COMMAND(command$)
  182. 2880 LOCal poll,pos
  183. 2883 IF (PEEK(NCR_SBCL) && Phases%)<>Command%
  184. 2885   PRINT #0;"Phase error; COMMAND expected." : RETurn 
  185. 2887 END IF 
  186. 2890 FOR pos=1 TO LEN(command$)
  187. 2900   POKE NCR_SODL,CODE(command$(pos))
  188. 2910   POKE NCR_SOCL,ACK+Command%
  189. 2920   FOR poll=1 TO time: IF PEEK(NCR_SBCL)<REQ : EXIT poll
  190. 2930   IF poll=time: PRINT #0;"REQ timeout in command." :STOP
  191. 2940   POKE NCR_SOCL,Command%
  192. 2950 END FOR pos
  193. 2953 FOR poll=1 TO time: IF PEEK(NCR_SBCL) && REQ : EXIT poll
  194. 2956 IF poll=time: PRINT #0;"REQ timeout after command." :STOP
  195. 2960 END DEFine COMMAND
  196. 2970 :
  197. 2980 DEFine PROCedure INQUIRY
  198. 2985 reply%=36
  199. 2990 COMMAND CHR$(18) & null$(1 TO 3) & CHR$(reply%) & null$(1)
  200. 3000 READ_DATA attribute$,reply%
  201. 3020 DriveType%=CODE(attribute$)
  202. 3030 PRINT "Drive ";unit%;": ";attribute$(9 TO reply%);" type ";DriveType%
  203. 3100 END DEFine INQUIRY
  204. 3110 :
  205. 3120 DEFine PROCedure ENQUIRY
  206. 3130 INQUIRY
  207. 3140 END DEFine ENQUIRY
  208. 3150 :
  209. 3160 REFERENCE info$
  210. 3170 DEFine PROCedure READ_DATA(info$,length%)
  211. 3175 LOCal poll,byte
  212. 3180 IF (PEEK(NCR_SBCL) && Phases%)<>DataIn%
  213. 3190   PRINT #0;"Phase error; DATA IN expected." : STOP
  214. 3195 END IF 
  215. 3210 info$=""
  216. 3220 FOR byte=1 TO length%
  217. 3230   info$=info$ & CHR$(PEEK(NCR_SBDL))
  218. 3240   POKE NCR_SOCL,ACK+DataIn%
  219. 3250   FOR poll=1 TO time: IF PEEK(NCR_SBCL)<REQ : EXIT poll
  220. 3260   IF poll=time: PRINT #0;"REQ timeout after message." :STOP
  221. 3270   POKE NCR_SOCL,DataIn%
  222. 3280 END FOR byte
  223. 3282 FOR poll=1 TO time: IF PEEK(NCR_SBCL) && REQ : EXIT poll
  224. 3284 IF poll=time: PRINT #0;"REQ timeout after data in." :STOP
  225. 3290 END DEFine READ_DATA
  226. 3300 :
  227. 3310 DEFine PROCedure NOW
  228. 3320 IF NOT debugging : RETurn 
  229. 3325 IF BUS_FREE
  230. 3330   PRINT "Bus free."
  231. 3340 ELSE 
  232. 3350   PRINT "Bus busy, expecting ";
  233. 3360   state=PEEK(NCR_SBCL) && Phases%
  234. 3370   SELect ON state
  235. 3380     =DataIn%,DataOut% : PRINT "DATA";
  236. 3390     =MessageIn%,MessageOut% : PRINT "MESSAGE";
  237. 3400     =Command% : PRINT "COMMAND";
  238. 3410     =StatusPhase% : PRINT "STATUS";
  239. 3420     =REMAINDER : PRINT "RESERVED";
  240. 3430   END SELect 
  241. 3440   IF state && 1 : PRINT " IN." : ELSE PRINT " OUT."
  242. 3445 END IF 
  243. 3450 END DEFine NOW
  244. 3460 :
  245. 3600 DEFine PROCedure RESET_DEVICE
  246. 3610 SEND_MESSAGE 12
  247. 3620 END DEFine RESET_DEVICE
  248. 3630 :
  249. 3660 DEFine PROCedure SEND_MESSAGE(code%)
  250. 3665 LOCal poll
  251. 3680 IF (PEEK(NCR_SBCL) && Phases%)<>MessageOut%
  252. 3690   PRINT #0;"Phase error; MESSAGE OUT expected." : RETurn 
  253. 3700 END IF 
  254. 3710 POKE NCR_SODL,code%
  255. 3720 POKE NCR_SOCL,ATN+MessageOut%
  256. 3730 POKE NCR_SOCL,ACK+ATN+MessageOut%
  257. 3740 FOR poll=1 TO time: IF PEEK(NCR_SBCL)<REQ : EXIT poll
  258. 3750 IF poll=time:PRINT #0;"REQ timeout after MESSAGE OUT.":STOP
  259. 3760 POKE NCR_SOCL,MessageOut%
  260. 3765 FOR poll=1 TO time: IF PEEK(NCR_SBCL) && REQ : EXIT poll
  261. 3767 IF poll=time: PRINT #0;"REQ timeout after status." :STOP
  262. 3770 END DEFine SEND_MESSAGE
  263. 3780 :
  264. 3790 DEFine PROCedure GET_STATUS
  265. 3792 LOCal poll
  266. 3794 IF (PEEK(NCR_SBCL) && Phases%)<>StatusPhase%
  267. 3796   PRINT #0;"Phase error; STATUS expected." : RETurn 
  268. 3798 END IF 
  269. 3799 status=PEEK(NCR_SBDL)
  270. 3800 POKE NCR_SOCL,ACK+StatusPhase%
  271. 3810 IF debugging : PRINT "Status  received: ";status
  272. 3820 FOR poll=1 TO time: IF PEEK(NCR_SBCL)<REQ : EXIT poll
  273. 3830 IF poll=time: PRINT #0;"REQ timeout after status." :STOP
  274. 3840 POKE NCR_SOCL,StatusPhase%
  275. 3845 FOR poll=1 TO time: IF PEEK(NCR_SBCL) && REQ : EXIT poll
  276. 3847 IF poll=time: PRINT #0;"REQ timeout after status." :STOP
  277. 3850 END DEFine GET_STATUS
  278. 3860 :
  279. 3870 DEFine PROCedure REQUEST_SENSE(unit%)
  280. 3875 ok=0
  281. 3880 NCR_SELECT unit%
  282. 3890 NCR_IDENTIFY
  283. 3895 length%=18 :REMark SCSI 2 Extended sense data please
  284. 3900 COMMAND CHR$(3) & null$(1 TO 3)& CHR$(length%) & null$(1)
  285. 3905 IF (PEEK(NCR_SBCL) && Phases%)<>StatusPhase%
  286. 3910   READ_DATA sense$,length% : ok=1
  287. 3915 END IF 
  288. 3920 GET_STATUS
  289. 3930 MESSAGE_IN
  290. 3934 sense=CODE(sense$(3))
  291. 3936 subSense=CODE(sense$(13))
  292. 3938 IF debugging
  293. 3939   PRINT_SENSE sense
  294. 3940   SCSI_REPORT subSense
  295. 3945 END IF 
  296. 3950 END DEFine REQUEST_SENSE
  297. 3960 :
  298. 3970 DEFine PROCedure SCSI_REPORT(op%)
  299. 3972 LOCal flag
  300. 3975 PRINT "SCSI sense request reports: ";
  301. 3977 flag=op%
  302. 3980 SELect ON flag
  303. 3990   =0  : PRINT "No sense."
  304. 3995   =2  : PRINT "No seek complete."
  305. 4000   =4  : PRINT "Drive not ready."
  306. 4010   =11 : PRINT "No medium in drive."
  307. 4020   =12 : PRINT "Unrecognised medium."
  308. 4030   =13 : PRINT "Medium is ejected."
  309. 4040   =14 : PRINT "Medium is stuck."
  310. 4050   =17 : PRINT "Uncorrectable error in data."
  311. 4060   =21 : PRINT "Seek not complete."
  312. 4070   =22 : PRINT "Header not found."
  313. 4075   =26 : PRINT "Parameter list error."
  314. 4080   =28 : PRINT "Not a digital audio track."
  315. 4090   =29 : PRINT "Not a CD ROM data track."
  316. 4100   =32 : PRINT "Invalid command."
  317. 4110   =33 : PRINT "Invalid subcode address."
  318. 4120   =34 : PRINT "Invalid command parameter."
  319. 4130   =36 : PRINT "Invalid command sequence."
  320. 4140   =37 : PRINT "Past the end of the medium."
  321. 4145   =38 : PRINT "Invalid parameter field."
  322. 4150   =40 : PRINT "Media changed."
  323. 4160   =41 : PRINT "Drive has been reset."
  324. 4170   =42 : PRINT "Error in parameter list."
  325. 4180   =44 : PRINT "Not currently playing audio."
  326. 4190   =45 : PRINT "Invalid message amid data."
  327. 4200   =47 : PRINT "SCSI unit not specified."
  328. 4210   =48 : PRINT "SCSI parity error."
  329. 4220   =49 : PRINT "Drive demands attention."
  330. 4230   =50 : PRINT "Command aborted."
  331. 4235   =58 : PRINT "No medium in drive."
  332. 4240   =62 : PRINT "Interface timeout."
  333. 4241   =71 : PRINT "SCSI parity error."
  334. 4242   =83 : PRINT "Medium change failed."
  335. 4245   =100: PRINT "Track is not suitable."
  336. 4250   =REMAINDER 
  337. 4260         PRINT "Error code ";flag
  338. 4270 END SELect 
  339. 4280 END DEFine SCSI_REPORT
  340. 4290 :
  341. 4300 DEFine PROCedure PRINT_SENSE(op%)
  342. 4310 LOCal flag
  343. 4315 PRINT "SCSI sense indicates: ";
  344. 4320 flag=op% && 15
  345. 4330 SELect ON flag
  346. 4340   =0 : PRINT "Nothing to report."
  347. 4350   =1 : PRINT "Recovered from read error."
  348. 4360   =2 : PRINT "Drive is not ready."
  349. 4370   =3 : PRINT "Medium in drive is defective."
  350. 4380   =4 : PRINT "Unrecoverable hardware error."
  351. 4390   =5 : PRINT "Illegal request."
  352. 4400   =6 : PRINT "Drive demands attention."
  353. 4410   =7 : PRINT "Drive protected against changes."
  354. 4420   =8 : PRINT "Medium is blank."
  355. 4430   =9 : PRINT "Vendor unique status."
  356. 4440   =10: PRINT "Copy aborted."
  357. 4450   =11: PRINT "Command abnormally terminated."
  358. 4460   =12: PRINT "Data matches."
  359. 4470   =13: PRINT "Too much data for this medium."
  360. 4480   =14: PRINT "Data does not match."
  361. 4490   =15: PRINT "Reserved status."
  362. 4500 END SELect 
  363. 4510 END DEFine PRINT_SENSE
  364. 4520 :
  365. 4530 DEFine PROCedure CD_TRACKS
  366. 4532 IF NOT NEC
  367. 4534   TOSH_TRACKS
  368. 4536 ELSE 
  369. 4540 NCR_SELECT CD
  370. 4550 NCR_IDENTIFY
  371. 4560 COMMAND CHR$(HEX("DE")) & null$(1 TO 9)
  372. 4565 IF StatusPhase%<>(PEEK(NCR_SBCL) && Phases%)
  373. 4567   READ_DATA info$,4
  374. 4568 END IF 
  375. 4570 GET_STATUS
  376. 4575 MESSAGE_IN
  377. 4577 IF status=0
  378. 4580   FirstTrack%=BCD(info$(1))
  379. 4585   IF debugging : PRINT "Minimum track number ";FirstTrack%
  380. 4590   LastTrack%=BCD(info$(2))
  381. 4595   IF debugging : PRINT "Maximum track number ";LastTrack%
  382. 4597 ELSE 
  383. 4598   REQUEST_SENSE CD
  384. 4600   FirstTrack%=1 : LastTrack%=0
  385. 4602 END IF 
  386. 4603 END IF 
  387. 4605 END DEFine CD_TRACKS
  388. 4610 :
  389. 4620 DEFine FuNction BCD(x$)
  390. 4630 RETurn 10 * (CODE(x$) DIV 16) + (CODE(x$) MOD 16)
  391. 4640 END DEFine BCD
  392. 4650 :
  393. 4660 DEFine FuNction BCD2$(num%)
  394. 4670 RETurn CHR$((num% MOD 10) + 16 * (num% DIV 10))
  395. 4680 END DEFine BCD2$
  396. 4685 :
  397. 4690 DEFine PROCedure CD_EJECT
  398. 4700 NCR_SELECT CD
  399. 4710 NCR_IDENTIFY
  400. 4720 COMMAND CHR$(HEX("DC")) & null$(1 TO 9)
  401. 4780 GET_STATUS
  402. 4785 IF status=0 : PRINT #0;"Disc ejected."
  403. 4790 MESSAGE_IN
  404. 4800 END DEFine CD_EJECT
  405. 4810 :
  406. 5010 DEFine PROCedure CD_PLAY(track%)
  407. 5020 NCR_SELECT CD
  408. 5030 NCR_IDENTIFY
  409. 5035 IF NEC
  410. 5040   COMMAND CHR$(HEX("D8")) & CHR$(1) & BCD2$(track%) & null$(1 TO 6) & CHR$(128)
  411. 5043 ELSE 
  412. 5045   COMMAND CHR$(72) & null$(1 TO 3) & CHR$(track%) & CHR$(1) & CHR$(0) & CHR$(LastTrack%) & CHR$(99) & CHR$(0)
  413. 5047 END IF 
  414. 5050 GET_STATUS
  415. 5060 MESSAGE_IN
  416. 5062 IF status
  417. 5064   PRINT #0;"CD track"!track%!"doesn't want to play."
  418. 5066   REQUEST_SENSE CD
  419. 5068 END IF 
  420. 5070 END DEFine CD_PLAY
  421. 5080 :
  422. 5090 DEFine PROCedure CD_PAUSE
  423. 5100 NCR_SELECT CD
  424. 5110 NCR_IDENTIFY
  425. 5115 IF NEC
  426. 5120   COMMAND CHR$(HEX("DA")) & null$(1 TO 9)
  427. 5125 ELSE 
  428. 5126   COMMAND CHR$(75) & null$(1 TO 9)
  429. 5127 END IF 
  430. 5130 GET_STATUS
  431. 5140 MESSAGE_IN
  432. 5150 END DEFine CD_PAUSE
  433. 5160 :
  434. 5170 DEFine PROCedure CD_CONTINUE
  435. 5180 NCR_SELECT CD
  436. 5190 NCR_IDENTIFY
  437. 5195 IF NEC
  438. 5200   COMMAND CHR$(HEX("D9")) & CHR$(4) &null$(1 TO 7) & CHR$(192)
  439. 5210   REMark PLAY_AUDIO type 3 mode 4 (no change)
  440. 5212 ELSE 
  441. 5214   COMMAND CHR$(75) & null$(1 TO 7) & CHR$(1) & CHR$(0)
  442. 5216 END IF 
  443. 5220 GET_STATUS
  444. 5230 MESSAGE_IN
  445. 5240 END DEFine CD_CONTINUE
  446. 5250 :
  447. 5252 DEFine PROCedure CD_MENU
  448. 5253 paused=-1 :REMark -2=Empty, -1=Stopped, 0=Playing, 1=Paused
  449. 5254 IF NOT debugging
  450. 5255   PAPER 0 : INK 4 : CLS
  451. 5256   CSIZE 2,1
  452. 5258   PRINT "Amiga QDOS SCSI CD PLAYER v1.1"
  453. 5259   PRINT "Simon N Goodwin September 1995"
  454. 5260   CSIZE 1,0
  455. 5261   REMark CSIZE 1,0 is good for up to 63 tracks; to make room for the
  456. 5262   REMark maximum of 99 use CSIZE 0,0 and boost window #1 to 23 lines
  457. 5263   PRINT : INK 7
  458. 5264   FOR i=14 TO 5 STEP -1.5 : CIRCLE 150,85,i
  459. 5265 END IF 
  460. 5266 DRIVE_IDENT CD
  461. 5267 REPeat disc
  462. 5268   IF NOT debugging
  463. 5269     AT 6,0 : CLS 2 : PRINT \"Tracks ";
  464. 5270     FOR t=FirstTrack% TO LastTrack%
  465. 5280       PAPER 2 : PRINT !" " & NUM$(t) & "  "!
  466. 5290       PAPER 0 : PRINT !!!
  467. 5295       IF (t && 7)=7 AND LastTrack%<32 : PRINT \\
  468. 5300     END FOR t
  469. 5305   END IF 
  470. 5310   PRINT \\
  471. 5315   REPeat commands
  472. 5317   IF NOT debugging: AT 16,0 : CLS 2
  473. 5320   PAPER 4 : INK 2
  474. 5325   IF paused=-2
  475. 5327     PRINT " No CD currently active -";
  476. 5328   ELSE 
  477. 5330     PRINT " Select a track number or";
  478. 5332   END IF 
  479. 5335   PRINT " type the first letter of a command "
  480. 5340   PAPER 0 : INK 4
  481. 5350   PRINT \"   ";
  482. 5355   IF paused>-2
  483. 5360     IF paused>0 : PRINT "[C] Continue";
  484. 5363     IF paused=0 : PRINT "[P] Pause";
  485. 5366     IF paused<0 : PRINT "[S] Start"; :ELSE PRINT "   [S] Stop";
  486. 5370     IF NEC : PRINT "   [E] Eject CD";
  487. 5371   END IF
  488. 5373   IF NOT NEC OR paused=-2 : PRINT "   [N] New CD";
  489. 5374   END IF 
  490. 5375   PRINT "   [Q] Quit"
  491. 5380   PAPER 4
  492. 5390   PRINT \,,,,,,,"     "
  493. 5400   PAPER 0 : INK 7
  494. 5410   k=CODE(INKEY$(#0,-1)) || 32
  495. 5415   PRINT #0;CHR$(k)
  496. 5420   SELect ON k
  497. 5430     =CODE("c") : IF paused>0 : CD_CONTINUE : paused=0
  498. 5440     =CODE("p") : IF paused=0 : CD_PAUSE : paused=1
  499. 5450     =CODE("e")
  500. 5455       IF paused>-2
  501. 5456         FirstTrack%=1 : LastTrack%=0 :REMark effectively, none
  502. 5457         CD_EJECT : paused=-2 : EXIT commands
  503. 5458       END IF 
  504. 5460     =CODE("n")
  505. 5465       CD_CONTROL 3
  506. 5466       REPeat poll : TEST_READY CD : IF NOT sense : EXIT poll
  507. 5468       CD_TRACKS : IF NEC : paused=-1
  508. 5469       EXIT commands
  509. 5470     =CODE("s")
  510. 5480       IF paused=-1
  511. 5490         CD_PLAY 1 : IF NOT status : paused=0
  512. 5500       ELSE 
  513. 5510         IF paused>=0 : CD_CONTROL 0 : paused=-1
  514. 5520       END IF 
  515. 5530     =CODE("q") : MODE 8 : MODE 4 : STOP
  516. 5540     =CODE("0") TO CODE("9") : k=k-48
  517. 5545      IF paused>-2
  518. 5550        IF k<=LastTrack% DIV 10
  519. 5552          IF k=0 AND LastTrack%<20
  520. 5553            CD_PLAY 1 : IF status=0 : paused=0 :REMark 0 can only mean 1!
  521. 5554          ELSE 
  522. 5555            GET_K2
  523. 5556            IF k2<>27 : CD_PLAY k*10+(k2-48) : paused=0
  524. 5557          END IF 
  525. 5558        ELSE 
  526. 5560          IF k>=FirstTrack% AND k<=LastTrack%:CD_PLAY k:IF status=0:paused=0
  527. 5570        END IF 
  528. 5580      END IF 
  529. 5730   END SELect 
  530. 5735   END REPeat commands
  531. 5740 END REPeat disc
  532. 5800 END DEFine CD_MENU
  533. 5810 :
  534. 5820 DEFine FuNction NUM$(q)
  535. 5830 IF q>9 : RETurn q
  536. 5835 IF LastTrack%<=9 : RETurn " " & q
  537. 5837 IF q<=LastTrack% DIV 10
  538. 5838   RETurn "0" & q
  539. 5839 ELSE 
  540. 5840   RETurn " " & q
  541. 5842 END IF 
  542. 5845 END DEFine NUM$
  543. 5850 :
  544. 5860 DEFine PROCedure GET_K2
  545. 5870 REMark Lots of ad-hoc-ery here
  546. 5900 CLS #0,116 : CLS #0,115 : PAN #0,0,115 :REMark Move cursor
  547. 5910 REPeat poll
  548. 5930   k2=CODE(INKEY$(#0,-1))
  549. 5940   SELect ON k2=27,CODE("0") TO CODE ("9") : EXIT poll
  550. 5945   IF k2=10 OR k2=32 : k2=k+58 : k=-1 : EXIT poll
  551. 5950   POKE_W HEX("DFF180"),2560 : REMark Error - so blink palette
  552. 5960   PAUSE 10
  553. 5970   POKE_W HEX("DFF180"),0
  554. 5975 END REPeat poll
  555. 5980 IF k>=0 : PRINT #0;CHR$(k2) : ELSE PRINT #0
  556. 5990 PAN #0,0,116 :REMark Cursor off
  557. 6000 END DEFine GET_K2
  558. 6010 :
  559. 6590 DEFine PROCedure TOSH_TRACKS
  560. 6600 NCR_SELECT CD
  561. 6610 NCR_IDENTIFY
  562. 6620 COMMAND CHR$(67) & null$(1 TO 7) & CHR$(4) & CHR$(0)
  563. 6630 READ_DATA info$,4
  564. 6640 FirstTrack%=CODE(info$(3))
  565. 6650   IF debugging : PRINT "Minimum track number ";FirstTrack%
  566. 6660 LastTrack%=CODE(info$(4))
  567. 6670   IF debugging : PRINT "Maximum track number ";LastTrack%
  568. 6680 GET_STATUS
  569. 6690 MESSAGE_IN
  570. 6700 END DEFine TOSH_TRACKS
  571. 6710 :
  572. 8500 DEFine PROCedure TEST_READY(unit%)
  573. 8510 NCR_SELECT unit%
  574. 8520 NCR_IDENTIFY
  575. 8530 COMMAND null$(1 TO 6)
  576. 8540 GET_STATUS
  577. 8550 MESSAGE_IN
  578. 8553 REQUEST_SENSE unit% :REMark Get full SENSE data
  579. 8560 END DEFine TEST_READY
  580. 8570 :
  581. 8580 DEFine PROCedure CD_CONTROL(op%)
  582. 8590 NCR_SELECT CD
  583. 8600 NCR_IDENTIFY
  584. 8610 COMMAND CHR$(27) & null$(1 TO 3) & CHR$(op% && 3) & null$(1)
  585. 8620 GET_STATUS
  586. 8630 MESSAGE_IN
  587. 8640 END DEFine CD_CONTROL
  588. 8650 :
  589. 8860 DEFine PROCedure DRIVE_RESET(unit%)
  590. 8870 NCR_SELECT unit%
  591. 8875 RESET_DEVICE
  592. 8877 REQUEST_SENSE unit%
  593. 8880 END DEFine DRIVE_RESET
  594. 8890 :
  595. 8895 DEFine PROCedure DRIVE_ABORT(unit%)
  596. 8900 REMark Test 2 - drive ABORT
  597. 8910 NCR_SELECT unit%
  598. 8920 NCR_ABORT
  599. 8925 END DEFine DRIVE_ABORT
  600. 8930 :
  601. 8940 DEFine PROCedure DRIVE_IDENT(unit%)
  602. 8945 NCR_SELECT unit%
  603. 8950 NCR_IDENTIFY
  604. 8960 REMark MESSAGE_IN
  605. 8970 INQUIRY
  606. 8980 GET_STATUS
  607. 8985 MESSAGE_IN
  608. 8990 END DEFine DRIVE_IDENT
  609. 8995 :
  610. 9000 DEFine PROCedure S
  611. 9010 SAVE_O CD_PLAYER_BAS
  612. 9020 END DEFine S
  613.